package com.xci.core.helper;

import net.sf.ehcache.Element;
import org.springframework.cache.Cache;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * 框架缓存操作类
 * @author 吕艳阳
 */
public class CacheHelper {
    /**
     * 获取缓存对象值
     * @param cache 缓存容器
     * @param key 缓存键
     * @param <T> 对象类型
     * @return 返回缓存容器中指定名称的对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T getCacheValue(Cache cache, Object key) {
        Cache.ValueWrapper wrapper = cache.get(key);
        if(wrapper == null) {
            return null;
        }
        return (T) wrapper.get();
    }

    /**
     * 获取缓存对象值
     * @param cache 缓存容器
     * @param key 缓存键
     * @param valueLoader 不存在缓存键时值加载器
     * @param <T> 对象类型
     * @return 返回缓存容器中指定名称的对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T getCacheValue(Cache cache, Object key, Callable<T> valueLoader) {
        Cache.ValueWrapper wrapper = cache.get(key);
        if(wrapper == null) {
            try {
                T current = valueLoader.call();
                cache.put(key, current);
                return current;
            } catch(Exception e) {
                throw new Cache.ValueRetrievalException(key, valueLoader, e);
            }
        }
        return (T) wrapper.get();
    }

    /**
     * 获取缓存对象集合
     * @param cache 缓存容器
     * @param <T> 对象类型
     * @return 返回缓存容器中所有的缓存值
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> getCacheValueList(Cache cache) {
        net.sf.ehcache.Cache ehcache = (net.sf.ehcache.Cache) cache.getNativeCache();
        Map<Object, Element> all = ehcache.getAll(ehcache.getKeysWithExpiryCheck());
        List<T> originList = new ArrayList<>();
        for(Element item : all.values()) {
            originList.add((T) item.getObjectValue());
        }
        return originList;
    }

    /**
     * 检查缓存容器中是否存在指定名称的对象
     * @param cache 缓存容器
     * @param key 缓存键
     * @return 存在返回true
     */
    public static boolean contains(Cache cache,Object key) {
        net.sf.ehcache.Cache ehcache = (net.sf.ehcache.Cache) cache.getNativeCache();
        return ehcache.isKeyInCache(key);
    }
}
